{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 定义区块结构"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import hashlib\n",
    "from datetime import datetime\n",
    "\n",
    "\n",
    "class Block:\n",
    "    \"\"\"\n",
    "        区块结构\n",
    "            prev_hash:      父区块哈希值\n",
    "            data:           区块内容\n",
    "            timestamp:      区块创建时间\n",
    "            hash:           区块哈希值\n",
    "    \"\"\"\n",
    "    def __init__(self, data, prev_hash):\n",
    "        # 将传入的父哈希值和数据保存到类变量中\n",
    "        self.previous_hash = prev_hash    \n",
    "        self.data = data\n",
    "        # 获取当前时间\n",
    "        self.timestamp = datetime.now().strftime(\"%Y-%m-%d %H:%M:%S\")\n",
    "\n",
    "        # 计算区块的哈希值\n",
    "        message = hashlib.sha256()\n",
    "        message.update(str(self.previous_hash).encode('utf-8'))\n",
    "        message.update(str(self.data).encode('utf-8'))\n",
    "        message.update(str(self.timestamp).encode('utf-8'))\n",
    "        self.hash = message.hexdigest()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "class BlockChain:\n",
    "    \"\"\"\n",
    "        区块链结构体\n",
    "            blocks:        包含的区块列表\n",
    "    \"\"\"\n",
    "    def __init__(self):\n",
    "        self.blocks = []\n",
    "\n",
    "    def add_block(self, block):\n",
    "        \"\"\"\n",
    "        添加区块\n",
    "        \"\"\"\n",
    "        self.blocks.append(block)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "其中需要注意的是第一个区块，也叫创世区块，它是一个特殊的区块，没有父区块，在区块链创建的时候会生成，定义如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 生成创世区块\n",
    "# 创世区块是第一个区块,无父区块哈希\n",
    "genesis_block = Block(data=\"创世区块\", prev_hash=\"\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 再新建两个区块, prev_hash分别为前一个哈希值\n",
    "new_block = Block(data=\"张三转给李四1个比特币\", prev_hash=genesis_block.hash)\n",
    "new_block2 = Block(data=\"张三转给王五2个比特币\", prev_hash=new_block.hash)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 新建一个区块链\n",
    "blockchain = BlockChain()\n",
    "\n",
    "# 将上面的几个区块添加到区块链中\n",
    "blockchain.add_block(genesis_block)\n",
    "blockchain.add_block(new_block)\n",
    "blockchain.add_block(new_block2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "区块链包含区块个数: 3\n",
      "\n",
      "上一个区块哈希：\n",
      "区块内容：创世区块\n",
      "区块哈希：9fcd3abbc11adc62f53bb15437db87b115fa9fcc579e682c91ce6363e4f0ba31\n",
      "\n",
      "\n",
      "上一个区块哈希：9fcd3abbc11adc62f53bb15437db87b115fa9fcc579e682c91ce6363e4f0ba31\n",
      "区块内容：张三转给李四1个比特币\n",
      "区块哈希：d083fbbb90c6906a525c6300c1572b02555a48eb49b94df998da8061e785288c\n",
      "\n",
      "\n",
      "上一个区块哈希：d083fbbb90c6906a525c6300c1572b02555a48eb49b94df998da8061e785288c\n",
      "区块内容：张三转给王五2个比特币\n",
      "区块哈希：81d3747303a2e6a26a269eed6e46f966ff869e2df878855d49e9428621a87562\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# 打印区块链\n",
    "\n",
    "print(\"区块链包含区块个数: %d\\n\" % len(blockchain.blocks))\n",
    "\n",
    "for block in blockchain.blocks:\n",
    "    print(\"上一个区块哈希：%s\" % block.previous_hash)\n",
    "    print(\"区块内容：%s\" % block.data)\n",
    "    print(\"区块哈希：%s\" % block.hash)\n",
    "    print(\"\\n\") # "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "上面的函数创建了一个区块链，并生成两个区块，加上创世区块一共三个区块。最后用Flask将生成的区块链展示一下。\n",
    "![blockchain_v1.png](blockchain_v1.png)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
